package ar.edu.uba.fi.jmit.monitorengine.core.rangeobserver;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Map;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.core.AbstractRangeObserver;
import ar.edu.uba.fi.jmit.monitorengine.core.Monitor;
import ar.edu.uba.fi.jmit.monitorengine.core.monitor.FieldValueMonitor;
import ar.edu.uba.fi.jmit.monitorengine.exception.MonitorEngineRuntimeException;

public class FieldValueRangeObserver extends AbstractRangeObserver {

	@Override
	protected Event createEvent(Monitor monitor, Map<String, Serializable> data) {
		FieldValueMonitor fieldValueMonitor = getFieldValueMonitor(monitor);
		Event event = new Event();
		event.setData(data);
		event.addData(ResourceProperties.getProperty(Constants.RANGE_MONITORED_CLASS), fieldValueMonitor.getMonitoredClass());
		event.addData(ResourceProperties.getProperty(Constants.RANGE_MONITORED_OBJECT), fieldValueMonitor.getIdObject());
		event.addData(ResourceProperties.getProperty(Constants.RANGE_MONITORED_OBJECT), fieldValueMonitor.getIdObject());
		event.addData(ResourceProperties.getProperty(Constants.RANGE_FIELD_NAME), fieldValueMonitor.getFieldName());
		event.setSource(this.getClass().getName());
		if(this.isAlert()) {
			event.setPriority(EventPriority.ALERT);
		}else {
			event.setPriority(EventPriority.NORMAL);
		}
		return event;
	}

	private FieldValueMonitor getFieldValueMonitor(Monitor monitor) {
		if(!(monitor instanceof FieldValueMonitor)) {
			throw new MonitorEngineRuntimeException("A FieldValueRangeObserver only observ a FieldValueMonitor");
		}
		return (FieldValueMonitor)monitor;
	}

	@Override
	protected Long getMonitorActualValue(Monitor monitor) {
		Serializable serializable = getFieldValueMonitor(monitor).getActualValue();
		if(!(serializable instanceof Number)) {
			throw new MonitorEngineRuntimeException("FieldValueRangeObserver can only be applied to numeric fields");
		}
		String number = serializable.toString();
		if(number.isEmpty()) {
			return 0L;
		}
		if(number.indexOf(".") != -1) {
			BigDecimal bigDecimal = new BigDecimal(number);
			return bigDecimal.setScale(0, BigDecimal.ROUND_UP).longValueExact();
		}
		return new Long(number);
	}

}
